package com.nnnu.wsnackshop.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nnnu.wsnackshop.config.JwtRealm;
import com.nnnu.wsnackshop.exception.ObjectException;
import com.nnnu.wsnackshop.mapper.PermissionsMapper;
import com.nnnu.wsnackshop.mapper.RolesMapper;
import com.nnnu.wsnackshop.pojo.dto.AssignPermissionDTO;
import com.nnnu.wsnackshop.pojo.entity.Permissions;
import com.nnnu.wsnackshop.pojo.entity.RolePermissions;
import com.nnnu.wsnackshop.mapper.RolePermissionsMapper;
import com.nnnu.wsnackshop.pojo.vo.PermissionVO;
import com.nnnu.wsnackshop.service.IRolePermissionsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.apache.shiro.SecurityUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 角色-权限关联 服务实现类
 * </p>
 *
 * @author zk
 * @since 2025-05-14
 */
@Service
@RequiredArgsConstructor
public class RolePermissionsServiceImpl extends ServiceImpl<RolePermissionsMapper, RolePermissions> implements IRolePermissionsService {
    private final RolesMapper roleMapper;
    private final PermissionsMapper permissionMapper;
    private final RolePermissionsMapper rpMapper;
    private final JwtRealm jwtRealm; // 用于清缓存

    @Override
    public Set<Integer> getPermissionsByRole(Long roleId) {
        // 校验角色存在
        if (roleMapper.selectById(roleId) == null) {
            throw new ObjectException("角色不存在: " + roleId);
        }
        // 查询中间表
        List<RolePermissions> list = rpMapper.selectList(
                new LambdaQueryWrapper<RolePermissions>().eq(RolePermissions::getRoleId, roleId)
        );
        return list.stream()
                .map(RolePermissions::getPermissionId)
                .collect(Collectors.toSet());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void assignPermissions(@NotNull AssignPermissionDTO dto) {
        Long roleId = dto.getRoleId();
        Set<Long> permIds = dto.getPermissionIds();

        // 1. 校验角色存在
        if (roleMapper.selectById(roleId) == null) {
            throw new ObjectException("角色不存在: " + roleId);
        }
        // 2. 校验所有权限 ID 都存在
        List<Long> bad = permIds.stream()
                .distinct()
                .filter(id -> permissionMapper.selectById(id) == null)
                .toList();
        if (!bad.isEmpty()) {
            throw new ObjectException("以下权限不存在: " + bad);
        }
        // 3. 删除旧关联
        rpMapper.delete(
                new LambdaQueryWrapper<RolePermissions>().eq(RolePermissions::getRoleId, roleId)
        );
        // 4. 批量插入新关联
        permIds.forEach(pid -> rpMapper.insert(new RolePermissions()
                .setRoleId(Math.toIntExact(roleId))
                .setPermissionId(Math.toIntExact(pid))
        ));
        // 5. 清除 Shiro 缓存，确保新权限生效
        jwtRealm.clearCache(SecurityUtils.getSubject().getPrincipals());
    }

    @Override
    public List<PermissionVO> listAllPermissions() {
        List<Permissions> perms = permissionMapper.selectList(null);
        return perms.stream().map(p -> BeanUtil.copyProperties(p, PermissionVO.class)).collect(Collectors.toList());
    }
}
